import string
import random
from functools import wraps
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
from extension import cache
from flask_mail import Message
from flask import Blueprint, request, jsonify, session
from werkzeug.security import generate_password_hash, check_password_hash
from extension import db, mail
from module import User
import datetime

auth_bp = Blueprint('auth', __name__)

def admin_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        current_user = get_jwt_identity()
        if current_user['role'] == 0:
            return f(*args, **kwargs)
        else:
            return jsonify({'message': 'You are not logged in!'}), 401
    return decorated_function

@auth_bp.route('/login', methods=['POST'])
def login():
    data = request.get_json(force=True)
    email = data['email']
    password = data['password']

    print(email, password)
    duration = datetime.timedelta(minutes=15)
    user = User.query.filter_by(mail=email).first()

    if user and check_password_hash(user.password, password):
        data = {
            'uid': user.uid,
            'name': user.name,
            'role': user.role
        }
        return jsonify({"token": create_access_token(data)}), 200
    else:
        return jsonify({"message": "Invalid credentials"}), 401

@auth_bp.route('/register', methods=['POST'])
def register():
    data = request.get_json()
    print(data)
    name = data['name']
    email = data['email']
    password = data['password']
    code = data['code']
    cache_code = cache.get(email)
    if not cache_code:
        return jsonify({"message": "please ask for email verification first"}), 400
    if User.query.filter_by(mail=email).first():
        return jsonify({'message': 'User already exists'}), 400
    if code == cache.get(email):
        new_user = User(name, generate_password_hash(password, method='pbkdf2:sha256'), email)
        db.session.add(new_user)
        db.session.commit()
        return jsonify({"message": "User created"}), 200
    return jsonify({"message": "Error occurs"}), 400

@auth_bp.route('/logout', methods=['POST'])
@jwt_required()
def logout():

    return jsonify({"message": "You have been logged out"}), 200

@auth_bp.route('/reset_password', methods=['POST'])
def reset_password():
    data = request.get_json()
    code = data['code']
    email = data['email']
    password = data['password']
    user = User.query.filter_by(mail=email).first()
    if not user:
        return jsonify({'message': 'Cannot find user'}), 404
    cache_code = cache.get(email)
    if not cache_code:
        return jsonify({"message": "Please ask for email verification first"}), 400
    if code == cache_code:
        user.set_password(generate_password_hash(password, method='pbkdf2:sha256'))
        db.session.commit()
        return jsonify({"message": "Password reset successful"}), 200
    return jsonify({"message": "Error occurs"}), 400

@auth_bp.route('/reset_verify', methods=['GET'])
def verify():
    email = request.args.get('email')
    if (not email):
        return jsonify({"message": "Please provide an email"}), 400
    user = User.query.filter_by(mail=email).first()
    if (user):
        code = send_verification_email(email)
        cache.set(email, code, timeout=300)
        return jsonify({"message": "An email is sent tu your email successful"}), 200
    else:
        return jsonify({"message": "Cannot find the user"}), 404

def send_verification_email(email):
    code = ''.join(random.choices(string.ascii_letters + string.digits, k=6))
    print([email])
    msg = Message(subject='Verification Code',
                  recipients=[email])
    msg.body = f'Your verification code is: {code}'

    try:
        mail.send(msg)
        return code

    except Exception as e:
        print(f"Failed to send email: {e}")
        return None

@auth_bp.route('/regist_verify', methods=['GET'])
def regist_verify():
    email = request.args.get('email')
    if (not email):
        return jsonify({"message": "Please enter your email"}), 400
    code = send_verification_email(email)

    cache.set(email, code, timeout=300)
    return jsonify({"message": "An email is sent tu your email successful"}), 200


@auth_bp.route('/get_myself', methods=['GET'])
@jwt_required()
def get_myself():
    current_user = get_jwt_identity()
    print(current_user)
    if current_user:
        user_info = {

            "uid": current_user['uid'],
            "name": current_user['name'],
            "role": current_user['role'],
        }
        return jsonify(user_info), 200
    else:
        return jsonify({"message": "User not found"}), 404

